package edu.iss.demo.web.controller;

import java.text.DateFormatSymbols;
import java.util.Calendar;
import java.util.Date;
import java.util.List;

import javax.servlet.http.HttpServletRequest;
import javax.validation.Valid;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.mvc.support.RedirectAttributes;

import edu.iss.demo.exception.EmployeeNotFound;
import edu.iss.demo.exception.LeaveDetailNotFound;
import edu.iss.demo.model.Employee;
import edu.iss.demo.model.LeaveDetail;
import edu.iss.demo.model.LeaveType;
import edu.iss.demo.model.PublicHoliday;
import edu.iss.demo.model.UserDetail;
import edu.iss.demo.service.EmployeeService;
import edu.iss.demo.service.LeaveDetailService;
import edu.iss.demo.service.LeaveTypeService;
import edu.iss.demo.service.PublicHolidayService;

@Controller
@RequestMapping(value = "/LeaveDetail")
public class LeaveDetailController {

	@Autowired
	private LeaveDetailService leaveDetailService;

	@Autowired
	private LeaveTypeService leaveTypeService;

	@Autowired
	private EmployeeService employeeService;

	@Autowired
	private PublicHolidayService publicHolidayService;

	@RequestMapping(value = "/create", method = RequestMethod.GET)
	public ModelAndView newLeaveDetailPage() {
		ModelAndView mav = new ModelAndView("applyLeave", "LeaveDetail",
				new LeaveDetail());
		List<LeaveType> LTList = leaveTypeService.findAll();
		mav.addObject("leaveTypelist", LTList);
		return mav;
	}

	@RequestMapping(value = "/create", method = RequestMethod.POST)
	public ModelAndView createNewLeaveDetail(
			@ModelAttribute @Valid LeaveDetail leaveDetail,
			HttpServletRequest r, BindingResult result,
			final RedirectAttributes redirectAttributes)
			throws EmployeeNotFound {

		if (result.hasErrors())
			return new ModelAndView("applyLeave");

		// Employee emp=employeeService.findById(2);

		UserDetail u = (UserDetail) r.getSession().getAttribute("userDetails");
		Employee emp = u.getEmployeeId();

		Date date = new Date();

		System.out
				.println("days---->"
						+ daysDiff(leaveDetail.getStartDate(),
								leaveDetail.getEndDate()));

		int days = (int) daysDiff(leaveDetail.getStartDate(),
				leaveDetail.getEndDate());

		
		days++; // due to cheange with values adnn laziness
		
		List<PublicHoliday> publicHolidays = publicHolidayService.findAll();
		Date startDate = leaveDetail.getStartDate();

		Calendar edcal = Calendar.getInstance();
		edcal.setTime(leaveDetail.getEndDate());

		edcal.add(Calendar.DATE, 1);

		Date endDate = edcal.getTime();

		// start the days check for the weekends and the public holidays
		for (; startDate.before(endDate);) {

			Calendar cal = Calendar.getInstance();
			cal.setTime(startDate);

			String dayName = new DateFormatSymbols().getWeekdays()[cal
					.get(Calendar.DAY_OF_WEEK)];
			System.out.println(dayName);

			// to check for the weekends
			if (dayName.equalsIgnoreCase("Saturday")
					|| dayName.equalsIgnoreCase("Sunday")) {

				days--;
			}
			// check into the public holidays
			for (PublicHoliday holiday : publicHolidays) {
				if (startDate.equals(holiday.getDate())) {

					days--;
				}
			}

			cal.add(Calendar.DATE, 1);
			startDate = cal.getTime();

		}

		if (leaveDetail.getLeaveType().getLeaveTypeId() == 1) {
			emp.setAnnualLeavesTaken(emp.getAnnualLeavesTaken() + days);
		} else if (leaveDetail.getLeaveType().getLeaveTypeId() == 2) {
			emp.setMedicalLeavesTaken(emp.getMedicalLeavesTaken() + days);
		}
		
		

		leaveDetail.setDays(days);
		leaveDetail.setApprovalStatus("pending");
		leaveDetail.setStatus("applied");
		leaveDetail.setApplicationDate(date);
		leaveDetail.setEmployeeId(emp);

		leaveDetailService.create(leaveDetail);
		employeeService.update(emp);

		ModelAndView mav = new ModelAndView();
		String message = "Your leave has been successfully applied!";

		mav.setViewName("AdminHome");

		redirectAttributes.addFlashAttribute("message", message);
		return mav;
	}

	public static long daysDiff(Date from, Date to) {
		return daysDiff(from.getTime(), to.getTime());
	}

	public static long daysDiff(long from, long to) {
		return Math.round((to - from) / 86400000D); // 1000 * 60 * 60 * 24
	}

	@RequestMapping(value = "/list", method = RequestMethod.GET)
	public ModelAndView leaveDetailPage(HttpServletRequest r) {
		ModelAndView mav = new ModelAndView("leaveAppList"); 
		UserDetail u = (UserDetail)r.getSession().getAttribute("userDetails");
		List<LeaveDetail> leaveDetailList = leaveDetailService.findLeavesForEmployee(u.getEmployeeId());
		mav.addObject("leaveDetailList", leaveDetailList);
		return mav;
	}
	
	
	@RequestMapping(value = "/Approvelist", method = RequestMethod.GET)
	public ModelAndView leaveDetailApprovePage(HttpServletRequest r) {
		System.out.println("Approvelist--->");
		ModelAndView mav = new ModelAndView("SubordinateLeaveList"); 
		
		UserDetail u = (UserDetail)r.getSession().getAttribute("userDetails");
		List<LeaveDetail> leaveDetailList = leaveDetailService.findSubordinateLeaves(u.getEmployeeId());
		mav.addObject("leaveDetailList", leaveDetailList);
		return mav;
	}
	

	@RequestMapping(value = "/edit-emp/{id}", method = RequestMethod.GET)
	public ModelAndView approveLeaveDetail(@PathVariable Long id , HttpServletRequest r)
			throws LeaveDetailNotFound {
		ModelAndView mav = new ModelAndView("SubordinateLeaveList"); 
		LeaveDetail leaveDetail = leaveDetailService.findById(id);
		// mav.addObject("LeaveDetail", leaveDetail);
		leaveDetail.setApprovalStatus("Approved");
		leaveDetailService.update(leaveDetail);
		UserDetail u = (UserDetail)r.getSession().getAttribute("userDetails");
		List<LeaveDetail> leaveDetailList = leaveDetailService.findSubordinateLeaves(u.getEmployeeId());
		mav.addObject("leaveDetailList", leaveDetailList);
		return mav;
	}

	@RequestMapping(value = "/edit-emp/reject/{id}", method = RequestMethod.GET)
	public ModelAndView rejectLeaveDetail(@PathVariable Long id, HttpServletRequest r)
			throws LeaveDetailNotFound {
		ModelAndView mav = new ModelAndView("SubordinateLeaveList"); 
		LeaveDetail leaveDetail = leaveDetailService.findById(id);
		// mav.addObject("LeaveDetail", leaveDetail);
		leaveDetail.setApprovalStatus("Rejected");
		leaveDetailService.update(leaveDetail);
		UserDetail u = (UserDetail)r.getSession().getAttribute("userDetails");
		List<LeaveDetail> leaveDetailList = leaveDetailService.findSubordinateLeaves(u.getEmployeeId());
		mav.addObject("leaveDetailList", leaveDetailList);
		return mav;
	}

	@RequestMapping(value = "/edit-emp/view/{id}", method = RequestMethod.GET)
	public ModelAndView viewLeaveDetail(@PathVariable Long id)
			throws LeaveDetailNotFound {
		System.out.println("leaveDetail-edit-emp");
		ModelAndView mav = new ModelAndView("leaveDetail-edit-emp");
		LeaveDetail leaveDetail = leaveDetailService.findById(id);
		mav.addObject("LeaveDetail", leaveDetail);
		// mav.addObject("LeaveDetail", leaveDetail);
		// List<LeaveDetail> leaveDetailList = leaveDetailService.findAll();
		// mav.addObject("leaveDetailList", leaveDetailList);
		return mav;
	}

	@RequestMapping(value = "/edit-emp/{id}", method = RequestMethod.POST)
	public ModelAndView editLeaveDetail(
			@ModelAttribute @Valid LeaveDetail leaveDetail,
			BindingResult result, @PathVariable Long id,
			final RedirectAttributes redirectAttributes)
			throws LeaveDetailNotFound {

		if (result.hasErrors())
			return new ModelAndView("leaveDetail-edit-emp");

		ModelAndView mav = new ModelAndView("AdminHome");
		String message = "Leave App was successfully updated.";

		leaveDetailService.update(leaveDetail);

		redirectAttributes.addFlashAttribute("message", message);
		return mav;
	}

	@RequestMapping(value = "/back", method = RequestMethod.POST)
	public ModelAndView loadHomeLeaveDetail(
			@ModelAttribute @Valid LeaveDetail leaveDetail,
			BindingResult result, final RedirectAttributes redirectAttributes, HttpServletRequest r)
			throws LeaveDetailNotFound {
		ModelAndView mav = new ModelAndView("SubordinateLeaveList"); 
		UserDetail u = (UserDetail)r.getSession().getAttribute("userDetails");
		List<LeaveDetail> leaveDetailList = leaveDetailService.findSubordinateLeaves(u.getEmployeeId());
		mav.addObject("leaveDetailList", leaveDetailList);
		return mav;
	}

}
